
// 输入一个值，返回其数据类型
function type(para) {
  return Object.prototype.toString.call(para)
}

// // 字符串去重
function unique1(arr) {
  return [...new Set(arr)]
}

function unique2(arr) {
  var obj = {};
  return arr.filter(ele => {
      if (!obj[ele]) {
          obj[ele] = true;
          return true;
      }
  })
}

function unique3(arr) {
  var result = [];
  arr.forEach(ele => {
      if (result.indexOf(ele) == -1) {
          result.push(ele)
      }
  })
  return result;
}

// 字符串去重
String.prototype.unique = function () {
  var obj = {},
      str = '',
      len = this.length;
  for (var i = 0; i < len; i++) {
      if (!obj[this[i]]) {
          str += this[i];
          obj[this[i]] = true;
      }
  }
  return str;
}

//去除连续的字符串 
function uniq(str) {
  return str.replace(/(\w)\1+/g, '$1')
}

// 圣杯模式的继承
function inherit(Target, Origin) {
  function F() {};
  F.prototype = Origin.prototype;
  Target.prototype = new F();
  Target.prototype.constructor = Target;
  // 最终的原型指向
  Target.prop.uber = Origin.prototype;
}

// 找出字符串中第一次只出现一次的字母
String.prototype.firstAppear = function () {
  var obj = {},
      len = this.length;
  for (var i = 0; i < len; i++) {
      if (obj[this[i]]) {
          obj[this[i]]++;
      } else {
          obj[this[i]] = 1;
      }
  }
  for (var prop in obj) {
     if (obj[prop] == 1) {
       return prop;
     }
  }
}

// 找元素的第n级父元素
function parents(ele, n) {
  while (ele && n) {
      ele = ele.parentElement ? ele.parentElement : ele.parentNode;
      n--;
  }
  return ele;
}

// 返回元素的第n个兄弟节点
function retSibling(e, n) {
  while (e && n) {
      if (n > 0) {
          if (e.nextElementSibling) {
              e = e.nextElementSibling;
          } else {
              for (e = e.nextSibling; e && e.nodeType !== 1; e = e.nextSibling);
          }
          n--;
      } else {
          if (e.previousElementSibling) {
              e = e.previousElementSibling;
          } else {
              for (e = e.previousElementSibling; e && e.nodeType !== 1; e = e.previousElementSibling);
          }
          n++;
      }
  }
  return e;
}

// 封装mychildren，解决浏览器的兼容问题
function myChildren(e) {
  var children = e.childNodes,
      arr = [],
      len = children.length;
  for (var i = 0; i < len; i++) {
      if (children[i].nodeType === 1) {
          arr.push(children[i])
      }
  }
  return arr;
}

// 判断元素有没有子元素
function hasChildren(e) {
  var children = e.childNodes,
      len = children.length;
  for (var i = 0; i < len; i++) {
      if (children[i].nodeType === 1) {
          return true;
      }
  }
  return false;
}

// 我一个元素插入到另一个元素的后面
Element.prototype.insertAfter = function (target, elen) {
  var nextElen = elen.nextElenmentSibling;
  if (nextElen == null) {
      this.appendChild(target);
  } else {
      this.insertBefore(target, nextElen);
  }
}

// 返回当前的时间（年月日时分秒）
function getDateTime() {
  var date = new Date(),
      year = date.getFullYear(),
      month = date.getMonth() + 1,
      day = date.getDate(),
      hour = date.getHours() + 1,
      minute = date.getMinutes(),
      second = date.getSeconds();
      month = checkTime(month);
      day = checkTime(day);
      hour = checkTime(hour);
      minute = checkTime(minute);
      second = checkTime(second);
   function checkTime(i) {
      if (i < 10) {
              i = "0" + i;
     }
    return i;
  }
  return "" + year + "年" + month + "月" + day + "日" + hour + "时" + minute + "分" + second + "秒"
}

// 获得滚动条的滚动距离
function getScrollOffset() {
  if (window.pageXOffset) {
      return {
          x: window.pageXOffset,
          y: window.pageYOffset
      }
  } else {
      return {
          x: document.body.scrollLeft + document.documentElement.scrollLeft,
          y: document.body.scrollTop + document.documentElement.scrollTop
      }
  }
}

// 获得视口的尺寸
function getViewportOffset() {
  if (window.innerWidth) {
      return {
          w: window.innerWidth,
          h: window.innerHeight
      }
  } else {
      // ie8及其以下
      if (document.compatMode === "BackCompat") {
          // 怪异模式
          return {
              w: document.body.clientWidth,
              h: document.body.clientHeight
          }
      } else {
          // 标准模式
          return {
              w: document.documentElement.clientWidth,
              h: document.documentElement.clientHeight
          }
      }
  }
}

// 获取任一元素的任意属性
function getStyle(elem, prop) {
  return window.getComputedStyle ? window.getComputedStyle(elem, null)[prop] : elem.currentStyle[prop]
}

// 绑定事件的兼容代码
function addEvent(elem, type, handle) {
  if (elem.addEventListener) { //非ie和非ie9
      elem.addEventListener(type, handle, false);
  } else if (elem.attachEvent) { //ie6到ie8
      elem.attachEvent('on' + type, function () {
          handle.call(elem);
      })
  } else {
      elem['on' + type] = handle;
  }
}

// 解绑事件
function removeEvent(elem, type, handle) {
  if (elem.removeEventListener) { //非ie和非ie9
      elem.removeEventListener(type, handle, false);
  } else if (elem.detachEvent) { //ie6到ie8
      elem.detachEvent('on' + type, handle);
  } else {
      elem['on' + type] = null;
  }
}

// 取消冒泡的兼容代码
function stopBubble(e) {
  if (e && e.stopPropagation) {
      e.stopPropagation();
  } else {
      window.event.cancelBubble = true;
  }
}
// 20、检验字符串是否是回文
function isPalina(str) {
  if (Object.prototype.toString.call(str) !== '[object String]') {
      return false;
  }
  var len = str.length;
  for (var i = 0; i < len / 2; i++) {
      if (str[i] != str[len - 1 - i]) {
          return false;
      }
  }
  return true;
}

// 检验字符串是否是回文
function isPalindrome(str) {
  str = str.replace(/\W/g, '').toLowerCase();
  console.log(str)
  return (str == str.split('').reverse().join(''))
}

// 获取url中的参数
function getWindonHref() {
  var sHref = window.location.href;
  var args = sHref.split('?');
  if (args[0] === sHref) {
      return '';
  }
  var hrefarr = args[1].split('#')[0].split('&');
  var obj = {};
  for (var i = 0; i < hrefarr.length; i++) {
      hrefarr[i] = hrefarr[i].split('=');
      obj[hrefarr[i][0]] = hrefarr[i][1];
  }
  return obj;
}

// 给定页面上的DOM元素,将访问元素本身及其所有后代(不仅仅是它的直接子元素)
// 对于每个访问的元素，函数讲元素传递给提供的回调函数
function traverse(element, callback) {
  callback(element);
  var list = element.children;
  for (var i = 0; i < list.length; i++) {
      traverse(list[i], callback);
  }
}

// 异步加载script
function loadScript(url, callback) {
  var oscript = document.createElement('script');
  if (oscript.readyState) { // ie8及以下版本
      oscript.onreadystatechange = function () {
          if (oscript.readyState === 'complete' || oscript.readyState === 'loaded') {
              callback();
          }
      }
  } else {
      oscript.onload = function () {
          callback()
      };
  }
  oscript.src = url;
  document.body.appendChild(oscript);
}

// cookie管理
var cookie = {
  set: function (name, value, time) {
      document.cookie = name + '=' + value + '; max-age=' + time;
      return this;
  },
  remove: function (name) {
      return this.setCookie(name, '', -1);
  },
  get: function (name, callback) {
      var allCookieArr = document.cookie.split('; ');
      for (var i = 0; i < allCookieArr.length; i++) {
          var itemCookieArr = allCookieArr[i].split('=');
          if (itemCookieArr[0] === name) {
              return itemCookieArr[1]
          }
      }
      return undefined;
  }
}

// 防抖
function debounce(handle, delay) {
  var timer = null;
  return function () {
      var _self = this,
          _args = arguments;
      clearTimeout(timer);
      timer = setTimeout(function () {
          handle.apply(_self, _args)
      }, delay)
  }
}

// 节流
function throttle(handler, wait) {
  var lastTime = 0;
  return function (e) {
      var nowTime = new Date().getTime();
      if (nowTime - lastTime > wait) {
          handler.apply(this, arguments);
          lastTime = nowTime;
      }
  }
}

// requestAnimFrame兼容性方法
window.requestAnimFrame = (function () {
  return window.requestAnimationFrame ||
      window.webkitRequestAnimationFrame ||
      window.mozRequestAnimationFrame ||
      function (callback) {
          window.setTimeout(callback, 1000 / 60);
      };
})();

// cancelAnimFrame兼容性方法
window.cancelAnimFrame = (function () {
  return window.cancelAnimationFrame ||
      window.webkitCancelAnimationFrame ||
      window.mozCancelAnimationFrame ||
      function (id) {
          window.clearTimeout(id);
      };
})();

// jsonp底层方法
function jsonp(url, callback) {
  var oscript = document.createElement('script');
  if (oscript.readyState) { // ie8及以下版本
      oscript.onreadystatechange = function () {
          if (oscript.readyState === 'complete' || oscript.readyState === 'loaded') {
              callback();
          }
      }
  } else {
      oscript.onload = function () {
          callback()
      };
  }
  oscript.src = url;
  document.body.appendChild(oscript);
}

// 获取url上的参数
function getUrlParam(sUrl, sKey) {
  var result = {};
  sUrl.replace(/(\w+)=(\w+)(?=[&|#])/g, function (ele, key, val) {
      if (!result[key]) {
          result[key] = val;
      } else {
          var temp = result[key];
          result[key] = [].concat(temp, val);
      }
  })
  if (!sKey) {
      return result;
  } else {
      return result[sKey] || '';
  }
}

// 格式化时间
function formatDate(t, str) {
  var obj = {
      yyyy: t.getFullYear(),
      yy: ("" + t.getFullYear()).slice(-2),
      M: t.getMonth() + 1,
      MM: ("0" + (t.getMonth() + 1)).slice(-2),
      d: t.getDate(),
      dd: ("0" + t.getDate()).slice(-2),
      H: t.getHours(),
      HH: ("0" + t.getHours()).slice(-2),
      h: t.getHours() % 12,
      hh: ("0" + t.getHours() % 12).slice(-2),
      m: t.getMinutes(),
      mm: ("0" + t.getMinutes()).slice(-2),
      s: t.getSeconds(),
      ss: ("0" + t.getSeconds()).slice(-2),
      w: ['日', '一', '二', '三', '四', '五', '六'][t.getDay()]
  };
  return str.replace(/([a-z]+)/ig, function ($1) {
      return obj[$1]
  });
}

// 函数柯里化
//是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数，并且返回接受余下的参数且返回结果的新函数的技术
function curryIt(fn) {
  var length = fn.length,
      args = [];
  var result = function (arg) {
      args.push(arg);
      length--;
      if (length <= 0) {
          return fn.apply(this, args);
      } else {
          return result;
      }
  }
  return result;
}

// 单例模式
function getSingle(func) {
  var result;
  return function () {
      if (!result) {
          result = new func(arguments);
      }
      return result;
  }
}

